#ifndef FILE_MANAGER_FILESYSTEM_LINUX
#define FILE_MANAGER_FILESYSTEM_LINUX

#include "jni.h"

#define LinuxPathAttributeImplClass "io/hellsinger/filesystem/linux/attribute/LinuxPathAttributeImpl"
#define LinuxPathAttributeImplConstructor "<init>"
#define LinuxPathAttributeImplConstructorSig "(IIIJJJJJJJJ)V"

static jclass globalLinuxPathAttributeImplClass;
static jclass globalLinuxPathAttributeInitMethod;

#define LinuxFileSystemAttributeImplClass "io/hellsinger/filesystem/linux/attribute/LinuxFileSystemAttributeImpl"
#define LinuxFileSystemAttributeImplConstructor "<init>"
#define LinuxFileSystemAttributeImplConstructorSig "(JJJJJJJJJJJ)V"

static jclass globalLinuxFileSystemAttributeClass;
static jmethodID globalLinuxFileSystemAttributeInitMethod;

#define LinuxGroupEntryImplClass "io/hellsinger/filesystem/linux/attribute/LinuxGroupEntryImpl"
#define LinuxGroupEntryImplConstructor "<init>"
#define LinuxGroupEntryImplConstructorSig "(I[B[B)V"

static jclass globalLinuxGroupEntryImplClass;
static jmethodID globalLinuxGroupEntryImplInitMethod;

#define LinuxUserEntryImplClass "io/hellsinger/filesystem/linux/attribute/LinuxUserEntryImpl"
#define LinuxUserEntryImplConstructor "<init>"
#define LinuxUserEntryImplConstructorSig "(I[B[B[B[B)V"

static jclass globalLinuxUserEntryImplClass;
static jmethodID globalLinuxUserEntryImplInitMethod;

#define LinuxObservablePathImplClass "io/hellsinger/filesystem/linux/operation/LinuxPathObserverImpl$LinuxObservablePathImpl"
#define LinuxObservablePathImplConstructor "<init>"
#define LinuxObservablePathImplConstructorSig "(III[B)V"

static jclass globalLinuxObservablePathImplClass;
static jmethodID globalLinuxObservablePathImplInitMethod;

#define ErrnoExceptionClass "io/hellsinger/filesystem/linux/error/ErrnoException"
#define ErrnoExceptionConstructor "<init>"
#define ErrnoExceptionConstructogSig "(Ljava/lang/String;ILjava/lang/String;)V"

static jclass globalErrnoExceptionClass;
static jmethodID globalErrnoExceptionInitMethod;

#define LinuxDirectoryEntryImplClass "io/hellsinger/filesystem/linux/directory/LinuxDirectoryEntryImpl"
#define LinuxDirectoryEntryImplConstructor "<init>"
#define LinuxDirectoryEntryImplConstructorSig "([BJI)V"

static jclass globalLinuxDirectoryEntryImplClass;
static jmethodID globalLinuxDirectoryEntryImplInitMethod;

void loadClass(JNIEnv *env, const char *name, jclass &ref);

void unloadClass(JNIEnv *env, jclass &ref);

void loadMethod(
        JNIEnv *env,
        jclass ref_class,
        const char *name,
        const char *sig,
        jmethodID &ref
);

void throwErrnoException(JNIEnv *env, const char *name, int number);

void throwErrnoException(JNIEnv *env, const char *name, int number, const char *desc);

#endif //FILE_MANAGER_FILESYSTEM_LINUX
